﻿using Authority.Logic;
using Basic.Logic;
using Basic.Model;
using Common.Model;
using Container.Library;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Network.Library;
using Serialize.Library;
using System;
using System.Text;
using System.Threading.Tasks;

namespace Api.Manage.App_Start
{
    /// <summary>
    /// 用户授权特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class UserAuthorizationAttribute : ActionFilterAttribute
    {

        /// <summary>
        /// webapi调用日志
        /// </summary>
        private SysApiMonitorLogEntity log = null;
        /// <summary>
        /// 接口请求参数
        /// </summary>
        private StringBuilder action_params = null;

        //是否需要验证
        private bool isValidate = false;

        /// <summary>
        /// 验证用户信息
        /// </summary>
        /// <param name="isValidate">是否验证</param>
        public UserAuthorizationAttribute(bool isValidate)
        {
            this.isValidate = isValidate;
        }

        /// <summary>
        ///  验证用户信息
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            #region 权限验证

            if (isValidate)
            {
                var id = HttpHelper.GetJwtUserId();
                var userService = UnityCIContainer.Instance.GetService<ISysUserService>();
                var userInfo = userService.LoadSingleById(id);

                ResultJsonInfo<string> resultInfo = new ResultJsonInfo<string>();

                if (userInfo.Success)
                {
                    if (!userInfo.Data.is_valid)
                    {
                        resultInfo.Code = ActionCodes.AccountBlocked;
                        resultInfo.Data = "用户被冻结，请联系管理人员！";
                        ActionException(filterContext, JsonHelper.ToJson(resultInfo));
                    }
                }
                else
                {
                    resultInfo.Code = ActionCodes.AccountNotExist;
                    resultInfo.Data = "无用户信息，请重新登录！";
                    ActionException(filterContext, JsonHelper.ToJson(resultInfo));
                }
            }

            #endregion

            #region 接口请求日记记录操作

            var descriptor = filterContext.ActionDescriptor as ControllerActionDescriptor;
            log = new SysApiMonitorLogEntity();
            log.action_name = descriptor.ActionName;
            if (descriptor.Parameters.Count > 0)
            {
                action_params =new StringBuilder();
                foreach (var item in descriptor.Parameters)
                {
                    action_params.Append($"{{{item.Name}:{JsonHelper.ToJson(filterContext.ActionArguments[item.Name])}}}");
                }
                log.action_params = action_params.ToString();
            }
            else
            {
                log.action_params = "";
            }
            log.controller_name = descriptor.ControllerName;
            log.start_time = DateTime.Now;
            log.http_method = filterContext.HttpContext.Request.Method;
            log.http_header = JsonHelper.ToJson(filterContext.HttpContext.Request.Headers.Values);
            log.request_ip = HttpHelper.GetIP();
            log.request_path = filterContext.HttpContext.Request.Path.ToString();
            #endregion

            base.OnActionExecuting(filterContext);
        }


        /// <summary>
        /// Action执行后发生
        /// </summary>
        /// <param name="actionExecutedContext">执行后的上下文</param>
        public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext.Exception == null)
            {
                //插入日志
                log.end_time = DateTime.Now;
                log.result_code = actionExecutedContext.HttpContext.Response.StatusCode.ToString();
                Task.Run(() => ApiMonitorLogServiceRedis.SaveApiMonitorLog(log));
            }
            base.OnActionExecuted(actionExecutedContext);
        }


        /// <summary>
        /// 失败返回处理
        /// </summary>
        /// <param name="filterContext"></param>
        /// <param name="message">失败信息</param>
        public void ActionException(ActionExecutingContext filterContext, string message)
        {
            var _Controller = filterContext.Controller as ControllerBase;
            filterContext.Result = _Controller.Content(message, "application/json;charset=utf-8;");
        }


    }
}
